import showWechatModal from './wechat_modal';

//判断ios9
function isIOS9() {
  //获取固件版本
  var getOsv = function () {
    var reg = /OS ((\d+_?){2,3})\s/;
    if (
      navigator.userAgent.match(/iPad/i) ||
      navigator.platform.match(/iPad/i) ||
      navigator.userAgent.match(/iP(hone|od)/i) ||
      navigator.platform.match(/iP(hone|od)/i)
    ) {
      var osv = reg.exec(navigator.userAgent);
      if (osv.length > 0) {
        return osv[0]
          .replace('OS', '')
          .replace('os', '')
          .replace(/\s+/g, '')
          .replace(/_/g, '.');
      }
    }
    return '';
  };
  var osv = getOsv();
  var osvArr = osv.split('.');
  //初始化显示ios9引导
  if (osvArr && osvArr.length > 0) {
    if (parseInt(osvArr[0]) >= 9) {
      return true;
    }
  }
  return false;
}

//通过iframe 打开Scheme 内置定时器
function openUrlIframe(jump_url, down_url) {
  var iframe = document.createElement('iframe');
  var body = document.body;
  iframe.style.cssText = 'display:none;width=0;height=0';
  var timer = null;

  body.appendChild(iframe);
  iframe.src = jump_url;
  timer = setTimeout(function () {
    window.location.href = down_url;
  }, 500);

  /*隐藏下载不要在弹出来*/
  document.addEventListener('visibilitychange', function () {
    var tag = document.hidden || document.webkitHidden;
    if (tag) {
      clearTimeout(timer);
    }
  });
  document.addEventListener('webkitvisibilitychange', function () {
    var tag = document.hidden || document.webkitHidden;
    if (tag) {
      clearTimeout(timer);
    }
  });
  document.querySelector('body').addEventListener('pagehide', function () {
    clearTimeout(timer);
  });
}

function whenLeavePage(fn) {
  const visibilityEvents = [
    'visibilitychange',
    'webkitvisibilitychange',
    'pagehide'
  ];
  const removeEventListener = () => {
    visibilityEvents.forEach(event =>
      document.removeEventListener(event, callback)
    );
    window.removeEventListener('unload', unload);
  };
  const callback = e => {
    removeEventListener();
    if (document.hidden || document.webkitHidden) {
      fn(e);
    }
  };
  const unload = e => {
    removeEventListener();
    fn(e);
  };

  window.addEventListener('unload', unload);
  visibilityEvents.forEach(event => document.addEventListener(event, callback));
  return removeEventListener;
}

function isIos() {
  if (typeof window === 'undefined') return false;
  const ua = window.navigator.userAgent;
  return /iphone|ipad|mac|ipod|iwatch/i.test(ua);
}

function isAndroid() {
  if (typeof window === 'undefined') return false;
  const ua = window.navigator.userAgent;
  return /android/i.test(ua);
}

function isWechatBrowser(userAgent) {
  return /MicroMessenger/i.test(userAgent);
}

function isQQBrowser(userAgent) {
  return /MQQBrowser/i.test(userAgent);
}

function isQQWebView(userAgent) {
  return /QBWebView/i.test(userAgent);
}

function isTencentBrowser(userAgent) {
  return isWechatBrowser(userAgent) || isQQBrowser(userAgent);
}

function isChromeBrowser(userAgent) {
  return /chrome|chromium/i.test(userAgent);
}

function isDingTalkBrowser(userAgent) {
  return /DingTalk/i.test(userAgent);
}

function makeTryJump({ jumpMethod, success, fail, finish }) {
  const isFunc = s => typeof s === 'function';
  return function tryJump(url, timeout) {
    return new Promise((resolve, reject) => {
      let jumpResult = null;
      const getCallbackParams = () => ({ jumpResult, url, timeout });
      const removeListener = whenLeavePage(() => {
        clearTimeout(timer);
        if (isFunc(success)) success(getCallbackParams());
        if (isFunc(finish)) finish(getCallbackParams());
        resolve();
      });
      const timer = setTimeout(() => {
        removeListener();
        if (isFunc(fail)) fail(getCallbackParams());
        if (isFunc(finish)) finish(getCallbackParams());
        reject(`Invoke app timeout ${timeout}.`);
      }, timeout);
      jumpResult = jumpMethod(url);
    });
  };
}

function makeTryJumpWithTag(tagMaker) {
  return makeTryJump({
    jumpMethod: url => {
      const $tag = tagMaker(url);
      return $tag;
    },
    finish: ({ jumpResult }) => {
      if (jumpResult) document.body.removeChild(jumpResult);
    }
  });
}

const jumpWithHref = makeTryJump({
  jumpMethod: url => (window.location.href = url)
});

const jumpWithLink = makeTryJumpWithTag(url => {
  const a = document.createElement('a');
  a.href = url;
  document.body.appendChild(a);
  a.click();
  return a;
});

const jumpWithFrame = makeTryJumpWithTag(url => {
  const iframe = document.createElement('iframe');
  iframe.style.cssText = 'display:none;width=0;height=0';
  iframe.src = url;
  document.body.appendChild(iframe);
  return iframe;
});

async function jumpOrDownload(jumpMethod, downloadUrl) {
  try {
    await jumpMethod();
  } catch (e) {
    if (downloadUrl) window.location.href = downloadUrl;
    throw e;
  }
}

function openAppInIos(options, settings) {
  const { userAgent, timeout } = settings;
  const { iosLink, iosUniversalLink, iosDownloadUrl, lang } = options;

  if (isQQWebView(userAgent)) {
    // QQ 浏览器无法使用 universal link 唤起
    if (isQQBrowser(userAgent)) {
      return jumpOrDownload(
        () => jumpWithHref(iosLink, timeout),
        iosDownloadUrl
      );
    }
    // QQ APP中无法唤起APP，显示弹窗
    return showWechatModal({ lang });
  }

  if (isWechatBrowser(userAgent) || isIOS9()) {
    return jumpOrDownload(() => jumpWithHref(iosUniversalLink, timeout));
  }
  return jumpOrDownload(() => jumpWithHref(iosLink, timeout), iosDownloadUrl);
}

function openAppInAndroid(options, settings) {
  const { userAgent, timeout } = settings;
  const {
    androidLink,
    lang,
    androidDownloadUrl,
    showWechatTips = true
  } = options;

  const tryJumpOrDownload = jumpMethod =>
    jumpOrDownload(() => jumpMethod(androidLink, timeout), androidDownloadUrl);

  if (isWechatBrowser(userAgent)) {
    if (showWechatTips) showWechatModal({ lang });
    return Promise.reject(
      new Error("Can'n invoke in wechat. show tips instead.")
    );
  }
  if (isDingTalkBrowser(userAgent)) {
    if (showWechatTips) showWechatModal({ lang });
    return Promise.reject(
      new Error("Can't invoke in DingTalk. show tips instead.")
    );
  }
  if (isQQBrowser(userAgent) || isChromeBrowser(userAgent)) {
    return tryJumpOrDownload(jumpWithLink);
  }
  return tryJumpOrDownload(jumpWithFrame);
}

function openAppAsync(options) {
  const userAgent = navigator.userAgent.toLowerCase();
  const timeout = 800;
  const settings = { userAgent, timeout };

  if (isIos()) {
    return openAppInIos(options, settings);
  } else {
    return openAppInAndroid(options, settings);
  }
}

//跳转app
function openApp(option) {
  let currentUrl = window.location.href;
  //android 使用Scheme协议
  var android_scheme = option.androidLink;
  //ios9 以下使用Scheme协议
  var ios_Scheme = option.iosLink;
  //ios9 以上使用 universal link
  var ios_universal_link = option.iosUniversalLinks;
  //IOS下载地址（Scheme协议时直接跳转）
  var ios_down_url = option.iosDownloadUrl;
  //安卓在QQ上的跳转地址
  var android_qq_url = option.QQAndroidUrl;
  //安卓下载地址
  //判断国际环境
  var android_down_url = '';
  if (option.IpCountryData == 1) {
    //国内
    android_down_url = option.officialDownloadUrl;
  } else {
    //国外
    android_down_url = option.androidDownloadUrl;
  }

  //获取网络状态
  var ua = navigator.userAgent.toLowerCase();
  //安卓和IOS判断
  if (isIos()) {
    //IOS系统
    if (
      ua.match(/MicroMessenger/i) == 'micromessenger' ||
      ua.match(/QQ/i) == 'qq'
    ) {
      //微信 QQ浏览器
      window.location.href = ios_universal_link;
      setTimeout(() => {
        window.location.href = currentUrl;
      }, 500);
      return false;
    } else if (isIOS9()) {
      //判断ios9 以上用 universal link
      window.location.href = ios_universal_link;
      setTimeout(() => {
        window.location.href = currentUrl;
      }, 500);
      return false;
    } else {
      //Ios9 以下
      openUrlIframe(ios_Scheme, ios_down_url);
    }
  } else {
    //安卓系统
    if (
      ua.match(/MicroMessenger/i) == 'micromessenger' ||
      ua.match(/DingTalk/i) == 'dingtalk'
    ) {
      //微信内 钉钉内 显示浮层 去浏览器打开
      option.cannotOpenApp();
      return false;
    } else if (ua.match(/QQ/i) == 'qq') {
      var a = document.createElement('a');
      a.setAttribute('href', android_scheme);
      document.body.appendChild(a);
      a.click();
      window.location.href = android_qq_url;
      return false;
      // chrome 浏览器需要在新的标签页打开才能唤起APP
    } else if (ua.match(/chrome|chromium/i)) {
      openWithATag(android_scheme, android_down_url);
    } else {
      openUrlIframe(android_scheme, android_down_url);
    }
  }
}

function openWithATag(schemeLink, downloadLink) {
  const $a = document.createElement('a');
  $a.href = schemeLink;
  document.body.appendChild($a);
  const id = setTimeout(() => {
    window.location.href = downloadLink;
  }, 500);
  whenLeavePage(() => clearTimeout(id));
  $a.click();
  document.body.removeChild($a);
}

const openAppFun = function (option) {
  // 绑定事件
  function bind(dom, event, fun) {
    // bind event
    if (dom.addEventListener) {
      dom.addEventListener(event, fun, !1);
    } else if (dom.attachEvent) {
      dom.attachEvent(event, fun);
    } else {
      throw new Error('不存在的方法');
    }
  }

  // 初始化
  function init(option) {
    if (option.button) {
      var elements = option.button;
      for (var i = 0; i < elements.length; i++) {
        elements[i].setAttribute('href', 'javascript:void(0)');
        bind(elements[i], 'click', function () {
          //					console.log(this);
          openApp(option);
        });
      }
    }
  }
  init(option);
};

export { openAppAsync, openApp, openUrlIframe };

export default {
  openAppAsync,
  openApp,
  openUrlIframe,
  openAppFun
};
